package com.block.channelunion.service.impl;

import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.crypto.SecureUtil;
import com.block.channelunion.model.dto.UnionCountDTO;
import com.block.channelunion.model.dto.UnionResultDTO;
import com.block.channelunion.model.vo.UnionLoginVO;
import com.block.channelunion.service.IChannelUnionCountInfoService;
import com.block.channelunion.service.IChannelUnionResultInfoService;
import com.block.channelunion.service.IChannleUnionLoginService;
import com.block.common.annotate.RedisLock;
import com.block.common.enums.ChargeTypeEnum;
import com.block.common.exception.NotifyExceptionService;
import com.block.common.model.dto.CountInfoDTO;
import com.block.common.model.dto.NewMemberDTO;
import com.block.common.model.vo.ResultInfoVO;
import com.block.common.service.IChannelCommonService;
import com.block.common.service.IMemberCommonService;
import com.block.common.service.LogFactory;
import com.block.db.entity.ApplicationInfo;
import com.block.db.entity.ChannelBaseInfo;
import com.block.db.entity.ChannelUnionResultInfo;
import com.block.db.entity.MemberBaseInfo;
import com.block.db.mapper.ChannelUnionResultInfoMapper;
import com.block.db.mapper.MemberBaseInfoMapper;
import com.market.member.enums.UserRegTypeEnum;
import com.market.member.enums.UserTypeEnum;
import com.market.member.service.IMemberBaseInfoService;
import org.slf4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;

import javax.annotation.Resource;
import java.time.LocalDate;

@Service
public class ChannelUnionLoginServiceImpl implements IChannleUnionLoginService {

    private Logger log = LogFactory.getUnionLog();

    @Resource
    MemberBaseInfoMapper memberBaseInfoMapper;
    @Autowired
    IChannelUnionCountInfoService channelUnionCountInfoService;
    @Resource
    ChannelUnionResultInfoMapper channelUnionResultInfoMapper;
    @Autowired
    IChannelUnionResultInfoService channelUnionResultInfoService;
    @Autowired
    NotifyExceptionService notifyExceptionService;
    @Autowired
    IMemberBaseInfoService memberBaseInfoService;
    @Autowired
    IChannelCommonService channelCommonService;
    @Autowired
    IMemberCommonService memberCommonService;

    @Override
    public ResultInfoVO unionCheck(String mobileMd5, String reqIp, ApplicationInfo applicationInfo, ChannelBaseInfo channelBaseInfo) {
        try {

            log.info("【渠道联登】撞库【channelCode】{}【channelName】{}【mobileMd5】{}",
                    channelBaseInfo.getChannelCode(), channelBaseInfo.getChannelName(), mobileMd5);
            mobileMd5 = mobileMd5.toLowerCase();

            MemberBaseInfo memberBaseInfo = memberBaseInfoMapper.getBaseUserInfoByMobileMd5Lock(mobileMd5);

            String dateInfo = LocalDate.now().toString();
            UnionCountDTO unionCountDTO = new UnionCountDTO();
            unionCountDTO.setDateInfo(dateInfo);
            unionCountDTO.setChannelCode(channelBaseInfo.getChannelCode());
            unionCountDTO.setChannelName(channelBaseInfo.getChannelName());
            unionCountDTO.setStatus("CHECK");
            channelUnionCountInfoService.saveUnionCountInfo(unionCountDTO);

            UnionLoginVO unionLoginVO = new UnionLoginVO();
            if (ObjectUtil.isNotEmpty(memberBaseInfo)){
                log.info("【渠道联登】用户已经存在");
                unionLoginVO.setStatus("001");
                unionLoginVO.setMessage("用户已经存在");
                return ResultInfoVO.success(unionLoginVO.toJsonObject());
            }

            unionLoginVO.setStatus("000");
            unionLoginVO.setMessage("可以登陆");
            ChannelUnionResultInfo unionResultInfo = channelUnionResultInfoService.saveUnloginResult(mobileMd5, applicationInfo, channelBaseInfo);
            if (ObjectUtil.isEmpty(unionResultInfo)){
                throw new RuntimeException("保存撞库信息失败");
            }
            unionLoginVO.setOrderNo(String.valueOf(unionResultInfo.getId()));
            return ResultInfoVO.success(unionLoginVO.toJsonObject());
        }catch (Exception exception){
            exception.printStackTrace();
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            String content = StrUtil.format("【channelCode】{}【channelName】{}【mobileMd5】{}",
                    channelBaseInfo.getChannelCode(), channelBaseInfo.getChannelName(), mobileMd5);
            notifyExceptionService.notifyNoticeInfo("UNION_CHECK", "联登撞库接口", content, exception);
        }
        return ResultInfoVO.error("操作失败");
    }

    @Override
    @Transactional
    @RedisLock(lockName = "UNION::LOGIN::MOBILE", key = "#mobile")
    public ResultInfoVO unionLogin(String mobile, String orderNo, String reqIp, ApplicationInfo applicationInfo, ChannelBaseInfo channelBaseInfo){

        try {
            log.info("【渠道联登】【channelCode】{}【channelName】{}【mobile】{}",
                    channelBaseInfo.getChannelCode(), channelBaseInfo.getChannelName(), mobile);

            ChannelUnionResultInfo unionResultInfo = channelUnionResultInfoMapper.selectEntityByIdLock(orderNo);
            if (ObjectUtil.isEmpty(unionResultInfo)){
                log.info("【渠道联登】撞库订单号不存在【orderNo】{}【mobile】{}", orderNo, mobile);
                return ResultInfoVO.error("撞库订单号不存在");
            }

            if (StrUtil.equals(SecureUtil.md5(mobile).toLowerCase(), unionResultInfo.getMobileMd5())){
                log.info("【渠道联登】撞库订单号不存在【orderNo】{}【mobile】{}", orderNo, mobile);
                return ResultInfoVO.error("联登手机号与撞库手机号不符合");
            }

            String dateInfo = LocalDate.now().toString();

            // 更新统计结果
            UnionCountDTO unionCountDTO = new UnionCountDTO();
            unionCountDTO.setDateInfo(dateInfo);
            unionCountDTO.setChannelCode(channelBaseInfo.getChannelCode());
            unionCountDTO.setChannelName(channelBaseInfo.getChannelName());

            // 更新联登结果
            UnionResultDTO unionResultDTO = new UnionResultDTO();
            unionResultDTO.setResultId(unionResultInfo.getId());

            MemberBaseInfo memberBaseInfo = memberBaseInfoMapper.getBaseUserInfoByPhoneLock(mobile);
            UnionLoginVO unionLoginVO = new UnionLoginVO();
            if (ObjectUtil.isNotEmpty(memberBaseInfo)){
                log.info("【渠道联登】用户已经存在");
                unionLoginVO.setStatus("001");
                unionLoginVO.setMessage("用户已经存在");

                unionResultDTO.setStatus("LOGIN_ERROR");
                unionResultDTO.setRemarkInfo("用户已存在");
                channelUnionResultInfoService.updateUnionLoginResult(unionResultDTO);

                unionCountDTO.setStatus("REGISTER");// 走到注册
                channelUnionCountInfoService.saveUnionCountInfo(unionCountDTO);
                return ResultInfoVO.success(unionLoginVO.toJsonObject());
            }

            NewMemberDTO newMemberDTO = new NewMemberDTO();
            newMemberDTO.setMobile(mobile);
            newMemberDTO.setChannelCode(channelBaseInfo.getChannelCode());
            newMemberDTO.setChannelName(channelBaseInfo.getChannelName());
            newMemberDTO.setRegAppCode(applicationInfo.getAppCode());
            newMemberDTO.setRegReqIP(reqIp);
            newMemberDTO.setType(UserTypeEnum.NORMAL.getValue());
            newMemberDTO.setRegType(UserRegTypeEnum.UNION.getValue());

            MemberBaseInfo memberInfo = memberCommonService.saveNewMemberInfo(newMemberDTO);
            if (ObjectUtil.isEmpty(memberInfo)){
                unionResultDTO.setStatus("REGISTER_ERROR");
                unionResultDTO.setRemarkInfo("保存用户信息失败");
                channelUnionResultInfoService.updateUnionLoginResult(unionResultDTO);

                unionCountDTO.setStatus("REGISTER");
                channelUnionCountInfoService.saveUnionCountInfo(unionCountDTO);
                return ResultInfoVO.error("联登失败");
            }

            //
            String unionLoginUrl = StrUtil.format("{}?u={}", channelBaseInfo.getPageUrl(), memberInfo.getUid());
            unionResultDTO.setUid(memberInfo.getUid());
            unionResultDTO.setUnionLoginUrl(unionLoginUrl);
            unionResultDTO.setStatus("SUCCESS");
            unionResultDTO.setRemarkInfo("成功");
            unionResultDTO.setMobile(mobile);
            channelUnionResultInfoService.updateUnionLoginResult(unionResultDTO);

            unionLoginVO.setStatus("000");
            unionLoginVO.setMessage("登陆成功");
            unionLoginVO.setUnionLoginUrl(unionLoginUrl);

            unionCountDTO.setStatus("SUCCESS");
            channelUnionCountInfoService.saveUnionCountInfo(unionCountDTO);

            // 统计注册信息
            CountInfoDTO countInfoDTO = new CountInfoDTO(channelBaseInfo.getChannelCode());
            countInfoDTO.setChargeType(ChargeTypeEnum.UNION.getValue());
            countInfoDTO.setRegisterCount(1);
            countInfoDTO.setRegisterCountReal(1);
            countInfoDTO.setRegisterCost(channelBaseInfo.getPriceAmount());
            channelCommonService.updateChannelCount(countInfoDTO);

            return ResultInfoVO.success(unionLoginVO.toJsonObject());
        }catch (Exception exception){
            exception.printStackTrace();
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            String content = StrUtil.format("【channelCode】{}【channelName】{}【mobile】{}",
                    channelBaseInfo.getChannelCode(), channelBaseInfo.getChannelName(), mobile);
            notifyExceptionService.notifyNoticeInfo("UNION_LOGIN", "联登接口", content, exception);
        }
        return ResultInfoVO.error("操作失败");
    }

}
